<?php
/*
 * @Descripttion: 
 * @version: 
 * @Author: Eugene
 * @Date: 2023-06-20 19:55:03
 * @LastEditors 肖宇 953675853@qq.com
 * @LastEditTime 2025-07-21 09:56:56
 */

namespace app\admin\controller\shop;

use app\admin\model\Admin;
use app\admin\model\AuthGroupAccess;
use app\common\controller\Backend;
use app\common\model\Acct;
use app\common\model\Category;
use app\common\model\Distribution;
use app\common\model\Distributionconfig;
use app\common\model\Distributionregion;
use app\common\model\shop\Goods;
use app\common\model\shop\goods\Acct as GoodsAcct;
use app\common\model\shop\Order as ShopOrder;
use app\common\model\shop\Ordergoods;
use Express;
use think\Db;
use think\exception\PDOException;
use think\exception\ValidateException;

/**
 * 商城订单
 *
 * @icon fa fa-circle-o
 */
class Order extends Backend
{

    /**
     * Order模型对象
     * @var \app\common\model\shop\Order
     */
    protected $model = null;
    protected $acctLimit = true;

    public function _initialize()
    {
        parent::_initialize();
        $this->model = new \app\common\model\shop\Order;
        $this->view->assign("statusList", $this->model->getStatusList());
        $this->view->assign("expressComList", $this->model->getExpressComList());
        $this->assignconfig("acct_visible", $this->auth->acct_id == 0 ? true : false);
        $this->view->assign("acct_id", $this->auth->acct_id);
        $this->assignconfig("acct_id", $this->auth->acct_id);
        $uids = Acct::column('admin_id');
        $adminlist = Admin::whereIn('id', $uids)->column('acct_id,nickname');
        $expresslist = Category::where('type', 'wl')->column('id,name');
        if ($this->auth->acct_id > 0) {
            $distributionlist = Distribution::where('pid', '>', 0)->where('acct_id', $this->auth->acct_id)->column('id,title');
        } else {
            $distributionlist = Distribution::where('pid', '>', 0)->column('id,title');
        }
        $this->assignconfig("distributionlist", $distributionlist);
        $this->assignconfig("expresslist", ['0' => '无'] + $expresslist);
        $this->assignconfig("adminlist", $adminlist);
    }



    /**
     * 默认生成的控制器所继承的父类中有index/add/edit/del/multi五个基础方法、destroy/restore/recyclebin三个回收站方法
     * 因此在当前控制器中可不用编写增删改查的代码,除非需要自己控制这部分逻辑
     * 需要将application/admin/library/traits/Backend.php中对应的方法复制到当前控制器,然后进行修改
     */


    /**
     * 查看
     */
    public function index()
    {

        //当前是否为关联查询
        $this->relationSearch = true;
        //设置过滤方法
        $this->request->filter(['strip_tags', 'trim']);
        if ($this->request->isAjax()) {
            ini_set('memory_limit', '4G');
            set_time_limit(300);
            //如果发送的来源是Selectpage，则转发到Selectpage
            if ($this->request->request('keyField')) {
                return $this->selectpage();
            }
            list($where, $sort, $order, $offset, $limit) = $this->buildparams();
            if ($this->request->get("user_id")) {
                $this->model->where('order.user_id', $this->request->get("user_id"));
            }
            // if (!$this->auth->acct_id) {
            //     $this->model->where('order.status', '>', '0');
            // }
            $list = $this->model
                ->with(['custom', 'user', 'wl', 'distribution', 'ordergoods'])
                ->where($where)
                ->order($sort, $order)
                ->paginate($limit);

            foreach ($list as $row) {

                if (isset($row->custom)) {
                    $row->getRelation('custom')->visible(['name']);
                }
                if (isset($row->wl)) {
                    $row->getRelation('wl')->visible(['name']);
                }

                if (isset($row->distribution) && $row->distribution) {
                    $row->getRelation('distribution')->visible(['title']);
                }
                if (isset($row->user)) {
                    $row->getRelation('user')->visible(['nickname']);
                }
                if (isset($row->ordergoods)) {
                    foreach ($row->ordergoods as $a) {
                        $a->hidden(['goods_info']);
                        // unset($a->goods_info);
                        // unset($a['goods_info_json']['content']);
                    }
                }

                // $row->getRelation('ordergoods')->visible(['total,pay_price,goods_info']);
            }

            $result = array("total" => $list->total(), "rows" => $list->items());

            return json($result);
        }
        return $this->view->fetch();
    }

    /**
     * 审核
     *
     * @param $ids
     * @return string
     * @throws DbException
     * @throws \think\Exception
     */
    public function examine($ids = null)
    {
        $row = $this->model->get($ids);
        if (!$row) {
            $this->error(__('No Results were found'));
        }
        $adminIds = $this->getDataLimitAdminIds();
        if (is_array($adminIds) && !in_array($row[$this->dataLimitField], $adminIds)) {
            $this->error(__('You have no permission'));
        }
        if (false === $this->request->isPost()) {
            $this->view->assign('row', $row);

            $check_stock = true;
            foreach ($row->ordergoods as $v) {
                $goods = GoodsAcct::where('goods_id', $v['goods_info_json']['id'])->where('acct_id', $row['acct_id'])->find();
                if ($goods && $goods['stock'] < $v['total']) {
                    $check_stock = false;
                    break;
                }
            }
            $this->view->assign('check_stock', $check_stock);
            return $this->view->fetch();
        }
        $params = $this->request->post('row/a');
        if (empty($params)) {
            $this->error(__('Parameter %s can not be empty', ''));
        }
        $params = $this->preExcludeFields($params);
        $result = false;
        Db::startTrans();
        try {
            //是否采用模型验证
            if ($this->modelValidate) {
                $name = str_replace("\\model\\", "\\validate\\", get_class($this->model));
                $validate = is_bool($this->modelValidate) ? ($this->modelSceneValidate ? $name . '.edit' : $name) : $this->modelValidate;
                $row->validateFailException()->validate($validate);
            }
            $result = $row->allowField(true)->save($params);
            Db::commit();
        } catch (ValidateException | PDOException | \Exception $e) {
            Db::rollback();
            $this->error($e->getMessage());
        }
        if (false === $result) {
            $this->error(__('No rows were updated'));
        }
        $this->success();
    }
    /**
     * 物流议价
     *
     * @param $ids
     * @return string
     * @throws DbException
     * @throws \think\Exception
     */
    public function bargain($ids = null)
    {
        $row = $this->model->get($ids);
        if (!$row) {
            $this->error(__('No Results were found'));
        }
        $adminIds = $this->getDataLimitAdminIds();
        if (is_array($adminIds) && !in_array($row[$this->dataLimitField], $adminIds)) {
            $this->error(__('You have no permission'));
        }
        if (false === $this->request->isPost()) {
            $this->view->assign('row', $row);
            return $this->view->fetch();
        }
        $params = $this->request->post('row/a');
        if (empty($params)) {
            $this->error(__('Parameter %s can not be empty', ''));
        }
        $params = $this->preExcludeFields($params);
        $result = false;
        Db::startTrans();
        try {
            //是否采用模型验证
            if ($this->modelValidate) {
                $name = str_replace("\\model\\", "\\validate\\", get_class($this->model));
                $validate = is_bool($this->modelValidate) ? ($this->modelSceneValidate ? $name . '.edit' : $name) : $this->modelValidate;
                $row->validateFailException()->validate($validate);
            }
            $dis = Distribution::get($row->distribution_id);
            if ($dis['type'] == 0) {
                $pay_fee=$row['pay_fee']- $row['send_fee'];
                $params['pay_fee'] = bcadd($pay_fee, $params['send_fee'], 2);
            }
            // $params['status'] = '0';
            $result = $row->allowField(true)->save($params);
            Db::commit();
        } catch (ValidateException | PDOException | \Exception $e) {
            Db::rollback();
            $this->error($e->getMessage());
        }
        if (false === $result) {
            $this->error(__('No rows were updated'));
        }
        $this->success();
    }
    /**
     * 运输
     *
     * @param $ids
     * @return string
     * @throws DbException
     * @throws \think\Exception
     */
    public function transit($ids = null)
    {
        $row = $this->model->get($ids);
        if (!$row) {
            $this->error(__('No Results were found'));
        }
        $adminIds = $this->getDataLimitAdminIds();
        if (is_array($adminIds) && !in_array($row[$this->dataLimitField], $adminIds)) {
            $this->error(__('You have no permission'));
        }
        if (false === $this->request->isPost()) {
            $this->view->assign('row', $row);
            return $this->view->fetch();
        }
        $params = $this->request->post('row/a');
        if (empty($params)) {
            $this->error(__('Parameter %s can not be empty', ''));
        }
        $params = $this->preExcludeFields($params);
        $result = false;
        Db::startTrans();
        try {
            //是否采用模型验证
            if ($this->modelValidate) {
                $name = str_replace("\\model\\", "\\validate\\", get_class($this->model));
                $validate = is_bool($this->modelValidate) ? ($this->modelSceneValidate ? $name . '.edit' : $name) : $this->modelValidate;
                $row->validateFailException()->validate($validate);
            }
            $params['status'] = '1';
            $result = $row->allowField(true)->save($params);
            Db::commit();
        } catch (ValidateException | PDOException | \Exception $e) {
            Db::rollback();
            $this->error($e->getMessage());
        }
        if (false === $result) {
            $this->error(__('No rows were updated'));
        }
        $this->success();
    }
    /**
     * 编辑
     *
     * @param $ids
     * @return string
     * @throws DbException
     * @throws \think\Exception
     */
    public function operation($ids = null)
    {
        $row = $this->model->get($ids);
        if (!$row) {
            $this->error(__('No Results were found'));
        }
        $adminIds = $this->getDataLimitAdminIds();
        if (is_array($adminIds) && !in_array($row[$this->dataLimitField], $adminIds)) {
            $this->error(__('You have no permission'));
        }
        if (false === $this->request->isPost()) {
            $this->view->assign('row', $row);
            return $this->view->fetch();
        }
        $params = $this->request->post('row/a');
        if (empty($params)) {
            $this->error(__('Parameter %s can not be empty', ''));
        }
        $params = $this->preExcludeFields($params);
        $result = false;
        Db::startTrans();
        try {
            //是否采用模型验证
            if ($this->modelValidate) {
                $name = str_replace("\\model\\", "\\validate\\", get_class($this->model));
                $validate = is_bool($this->modelValidate) ? ($this->modelSceneValidate ? $name . '.edit' : $name) : $this->modelValidate;
                $row->validateFailException()->validate($validate);
            }
            if (isset($params['send_type'])&&$params['send_type'] == 1) {
                if ($row['type'] == 0) {
                    $total_ed = bcadd($row->send_fee, $row->original_price, 2);
                } else {
                    $total_ed = $row->original_price;
                }
                $acct = Acct::get($row->acct_id);
                if (($acct->admin->money ?? 0) < $total_ed) {
                    exception('授信余额不足请充值');
                }
            }
            $result = $row->allowField(true)->save($params);
            Db::commit();
        } catch (ValidateException | PDOException | \Exception $e) {
            Db::rollback();
            $this->error($e->getMessage());
        }
        if (false === $result) {
            $this->error(__('No rows were updated'));
        }
        $this->success();
    }
    function detail($ids = null)
    {

        $row = $this->model->get($ids);
        if (!$row) {
            $this->error(__('No Results were found'));
        }
        $adminIds = $this->getDataLimitAdminIds();
        if (is_array($adminIds) && !in_array($row[$this->dataLimitField], $adminIds)) {
            $this->error(__('You have no permission'));
        }
        if (false === $this->request->isPost()) {
            $this->view->assign('row', $row);
            return $this->view->fetch();
        }
    }
    /**
     * 查询物流
     */
    public function query()
    {
        $get = $this->request->param();
        $get['express_com'] = Category::where('id', $get['express_id'])->value('nickname');
        $get['mobile'] = $this->model->where('id', $get['ids'])->value('consign_mobile');
        $kd = new Express($get);
        $wuliu = $kd->getOrderTracesByJson();
        $this->assign('data', isset($wuliu['status']) && $wuliu['status'] == 200 && count((array) $wuliu['data']) ? (array) $wuliu['data'] : $wuliu['message'] ?? '');
        return $this->view->fetch();
    }


    function add()
    {
        if (false === $this->request->isPost()) {
            return $this->view->fetch();
        }
        $params = $this->request->post('row/a');
        if (empty($params)) {
            $this->error(__('Parameter %s can not be empty', ''));
        }
        $params = $this->preExcludeFields($params);

        if ($this->dataLimit && $this->dataLimitFieldAutoFill) {
            $params[$this->dataLimitField] = $this->auth->id;
        }
        $result = false;
        Db::startTrans();
        try {
            //是否采用模型验证
            if ($this->modelValidate) {
                $name = str_replace("\\model\\", "\\validate\\", get_class($this->model));
                $validate = is_bool($this->modelValidate) ? ($this->modelSceneValidate ? $name . '.add' : $name) : $this->modelValidate;
                $this->model->validateFailException()->validate($validate);
            }
            $pay_fee = 0;
            $goods_list = [];
            $order_goods_data = [];
            // $goods = 
            // $data = ShopOrder::yuOrder(json_decode($params['goods'],1), $params['distribution_id'], $address_id ?? 0, $params['custom_id'], 1);
            $custom = \app\common\model\Custom::get($params['custom_id']);
            if (!$custom) {
                exception('请选择客户');
            }
            $user = $custom->user;
            if (!$user) {
                exception('客户未绑定销售');
            }

            // var_dump($data);die;

            // $order_id = ShopOrder::addOrder($params['custom_id'], $address_id ?? 0, $user['id'], $data, $params['pay_image'], $params['distribution_id'], $params['remark'] ?? 'remark', $orderid ?? 0);

            $goods_info = json_decode($params['goods'], true);



            $goods_list = [];
            $total_money = $total = $total_original_price = $pay_fee = $total_fee = $send_fee = $weight = $only_fx_price = 0;
            foreach ($goods_info as $v) {

                $acct_product = GoodsAcct::get($v['id']);
                $product = $acct_product->goods;
                if (!$product) {
                    exception('商品不存在');
                }
                $product['num'] = $v['num'];
                // if (isset($product['goods_acct']['price']) && $product['goods_acct']['price'] > 0) {
                //     $goods_price = $product['goods_acct']['price'];
                //     $original_price = $product['goods_acct']['purchase_price'];
                // } else {
                //     $original_price = 0;
                //     $goods_price = $product['price'];
                // }

                $goods_price = $acct_product['price'];
                $original_price = $acct_product['purchase_price'];

                if (isset($v['pay_money']) && $v['pay_money'] > $goods_price) {
                    $pay_money = $v['pay_money'];
                } else {
                    $pay_money = $goods_price;
                }
                $product['pay_money'] = $pay_money;
                $product['original_price'] = $original_price;
                $product['total_money'] = bcmul($v['num'], $goods_price, 2);
                $product['total_original_price'] = bcmul($v['num'], $original_price, 2);
                $product['pay_fee'] = bcmul($v['num'], $pay_money, 2);
                $total_original_price += $product['total_original_price'];
                $total_fee += $product['total_money'];
                $total_money += $product['pay_fee'];
                $pay_fee += $product['pay_fee'];
                $total += $v['num'];
                $product['total_weight'] = bcmul($product['weight'], $product['num'], 2);
                $weight += $product['total_weight'];

                if ($product['only_fx'] == 1) {
                    $only_fx_price += $product['total_money'];
                }

                unset($product['content']);
                array_push($goods_list, $product);
            }

            // if ($address_id) {
            //     $addressinfo = Address::get($address_id);
            //     $city = $addressinfo['city'];
            // } else {
            //     $custominfo = Custom::get($custom_id);
            //     $city = $custominfo['city'];
            // }
            $total_weight = $weight;
            $city = Db::name('cnarea')->where('area_code', $params['area'] ?? '')->value('merger_name');
            $distribution_id = $params['distribution_id'] ?? 0;

            if (empty($city)) {
                exception('请选择收货地址');
            }
            $city_arr = explode(',', $city);
            $dis = Distribution::get($distribution_id);
            $dispid = Distribution::get($dis['pid']);
            if ($dis['weight'] > $total_weight) {
                exception('下单重量不得小于起送重量');
            }
            if ($dispid['title'] != '物流') {
                $distribution = Distributionregion::whereLike('city', '%' . $city_arr[0] . '%')->where('pid', $distribution_id)->find();
                if (!$distribution) {
                    exception('地址错误,请确认收货地址');
                }
                if ($distribution) {
                    $send_fee = $distribution->send_fee;
                    $expense = 0;
                    if ($weight > 0) {
                        if ($weight > $distribution->weight) {
                            // $weight -= $distribution->weight;
                            $config = Distributionconfig::where(['pid' => $distribution->id])->order('weight asc')->select();
                            foreach ($config as $vv) {
                                if ($vv->weight >= $weight) {
                                    $expense = $vv->send_fee;
                                    break;
                                } else {
                                    $expense = $vv->send_fee;
                                }
                            }
                        }
                    }
                    if ($send_fee > 0 && $weight > 0 && $expense > 0) {
                        $send_fee = ceil($weight) * $expense;
                        // $send_fee = bcadd($send_fee, $czf, 2);
                    }
                    if ($dis['type'] == '0') {
                        $pay_fee = bcadd($pay_fee, $send_fee, 2);
                    }
                }
            }




            $acct = Acct::get($user->acct_id);


            $status = '0';

            // if ($dispid['title'] == '物流') {
            //     $status = '-0.4';
            // }
            if ($dis['type'] == 0) {
                $total_ed = bcadd($send_fee, $total_original_price, 2);
            } else {
                $total_ed = $total_original_price;
            }
            if (($acct->admin->money ?? 0) < $total_ed) {
                exception('授信余额不足请充值');
            }
            $order = new ShopOrder();

            $order->isUpdate(false);
            $sn = sn('shop_order', 'order_no', 'NO');

            $data = [
                'order_no' => $sn,
                'user_id' => $user->id,
                'custom_id' => $custom->id,
                'total' => $total,
                'total_weight' => $total_weight,
                'total_fee' => $total_fee,
                'original_price' => $total_original_price,
                'only_fx_price' => $only_fx_price,
                'remark' => $params['remark'] ?? '',
                'distribution_id' => $distribution_id,
                'type' => $dis['type'],
                'pay_fee' => $pay_fee,
                'consign_name' => $custom['name'],
                'consign_mobile' => $custom['phone'],
                'consign_address' => implode('/', $city_arr) . '/' . ($params['consign_address'] ?? $custom['address']),
                'pay_image' => $params['pay_image'],
                'status' => $status,
                'send_fee' => $send_fee,
                'acct_id' => $user->acct_id,
                'source_type' => 1
            ];

            $custom->lasttime = time();
            $custom->save();
            $res = $order->allowField(true)->save($data);

            if ($res) {

                $array = [];
                foreach ($goods_list as $v) {
                    if ($v['limited'] > 0) {
                        if ($v['custom'] == 0 && $v['limited'] < $v['num']) {
                            exception('【' . $v['title'] . '】商品限制购买数量' . $v['limited'] . '/' . $v['unit']);
                        }
                        if ($v['custom'] == 1 && $v['limited'] > $v['num']) {
                            exception('【' . $v['title'] . '】商品起购数量' . $v['limited'] . '/' . $v['unit']);
                        }
                    }
                    array_push($array, [
                        'order_id' => $order->id,
                        'goods_info' => json_encode($v),
                        'price' => $v['price'],
                        'pay_price' => $v['pay_money'],
                        'original_price' => $v['original_price'],
                        'total_original_price' => $v['total_original_price'],
                        'total' => $v['num'],
                        'total_weight' => $v['total_weight'],
                        'acct_id' => $user->acct_id,
                    ]);
                }
                $Ordergoods = new Ordergoods();
                $Ordergoods->allowField(true)->saveAll($array);

                // Acctmoneylog::money(-$total_ed, $acct->admin_id, '订单下单', '', $order->id);
            } else {
                exception('下单失败');
            }

            Db::commit();
        } catch (ValidateException | PDOException | \Exception $e) {
            Db::rollback();
            $this->error($e->getMessage());
        }

        $this->success();
    }
}
